package com.atguigu.srb.core.service.impl;

import com.atguigu.common.exception.BusinessException;
import com.atguigu.common.results.ResultCodeEnum;
import com.atguigu.srb.base.utils.JwtUtils;
import com.atguigu.srb.core.pojo.entity.BorrowInfo;
import com.atguigu.srb.core.mapper.BorrowInfoMapper;
import com.atguigu.srb.core.pojo.entity.Borrower;
import com.atguigu.srb.core.pojo.entity.IntegralGrade;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.pojo.vo.BorrowInfoApprovalVO;
import com.atguigu.srb.core.pojo.vo.BorrowInfoDetailVo;
import com.atguigu.srb.core.pojo.vo.BorrowerDetailVO;
import com.atguigu.srb.core.pojo.vo.BorrowerInfoVo;
import com.atguigu.srb.core.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 借款信息表 服务实现类
 * </p>
 *
 * @author Atguigu
 * @since 2022-10-24
 */
@Service
public class BorrowInfoServiceImpl extends ServiceImpl<BorrowInfoMapper, BorrowInfo> implements BorrowInfoService {
    @Autowired
    UserInfoService userInfoService;
    @Autowired
    IntegralGradeService integralGradeService;
    @Autowired
    DictService dictService;
    @Autowired
    BorrowerService borrowerService;
    @Autowired
    LendService lendService;
    @Override
    public void saveBorrowerInfo(BorrowInfo borrowInfo, String token) {
        //1、获取用户id：确保用户已登录
        Long userId = JwtUtils.getUserId(token);
        //2、校验用户状态： 是否被锁定、账户是否已绑定、借款人信息是否提交审核
        UserInfo userInfo = userInfoService.getById(userId);
        if(userInfo.getStatus()!=1){
            throw new BusinessException(ResultCodeEnum.LOGIN_LOKED_ERROR);
        }
        if(userInfo.getBindStatus()!=1){
            throw new BusinessException(ResultCodeEnum.USER_NO_BIND_ERROR);
        }
        if(userInfo.getBorrowAuthStatus()!=2){
            throw new BusinessException(ResultCodeEnum.USER_NO_AMOUNT_ERROR);
        }
        //3、验证用户申请的借款额度是否被允许
        BigDecimal amount = borrowInfo.getAmount();//用户提交的本次借款的额度
        //查询当前用户的积分等级对应的最高借款额度
        Integer integral = userInfo.getIntegral();
        IntegralGrade integralGrade = integralGradeService.getOne(new LambdaQueryWrapper<IntegralGrade>()
                .le(IntegralGrade::getIntegralStart, integral)
                .ge(IntegralGrade::getIntegralEnd, integral)
                .last("limit 1"));
        //integralGrade.getBorrowAmount().compareTo(amount) 比较大小，  1 和 0 代表传入的amount小于等于
        if(integralGrade==null || integralGrade.getBorrowAmount().compareTo(amount)==-1){
            throw new BusinessException(ResultCodeEnum.USER_AMOUNT_LESS_ERROR);
        }
        //4、保存借款信息到数据库表中： borrow_info
        borrowInfo.setUserId(userId); //将借款信息绑定给会员
        borrowInfo.setStatus(1); //设置状态为审核中
        //前端输入的年利率是整数%   ,数据库保存时 需要转为 整数/100的结果
        borrowInfo.setBorrowYearRate(borrowInfo.getBorrowYearRate().divide(new BigDecimal("100")));

        this.save(borrowInfo);
    }

    @Override
    public Integer getStatus(String token) {
        Long userId = JwtUtils.getUserId(token);
        //查询最新的一个 借款数据
        //select * from xxx
        //select status from xxx
        BorrowInfo borrowInfo = this.getOne(new LambdaQueryWrapper<BorrowInfo>()
                .select(BorrowInfo::getStatus)
                .eq(BorrowInfo::getUserId, userId)
                .orderByDesc(BorrowInfo::getCreateTime)
                .last("limit 1"));
        if(borrowInfo==null){
            return 0; //返回状态0
        }
        //返回查询到的借款数据状态
        return borrowInfo.getStatus();
    }

    @Override
    public void listPage(Page<BorrowerInfoVo> page, String key) {
        //分页数据的查询
        //this.page(); 查询borrowerInfo对象的分页数据，页面需要的是borrowerInfoVo对象的分页数据
        //参考Mapper中实现的方法，传入QueryWrapper对象  以后通过QueryWrapper对象可以传入任意的条件处理
        /*
        mybatisplus的自定义方法：
            1、如果传入page对象，并且已经配置了分页拦截器，那么本次查询 myb会自动通过拦截器拼接分页查询的sql
            2、如果传入的是Wrapper对象，自定义sql时可以使用${ew.customSqlSegment}获取设置到Wrapper中的条件

         */
        QueryWrapper<BorrowerInfoVo> queryWrapper = new QueryWrapper<BorrowerInfoVo>();
        if(!StringUtils.isEmpty(key)){
            //根据手机号码模糊查询
            //设置的条件最终生成了查询sql后拼接的字符串
            queryWrapper.like("t2.mobile" , key);
        }
        //mapper中的自定义方法返回结果需要我们手动解析使用
        List<BorrowerInfoVo> borrowerInfoVos =  baseMapper.selectBorrowerInfoVoPage(page , queryWrapper);
        //修改每一个BorrowerInfoVo的状态 和年利率
        borrowerInfoVos.forEach(borrowerInfoVo -> {
            borrowerInfoVo.setBorrowYearRate(borrowerInfoVo.getBorrowYearRate()
                    .multiply(new BigDecimal("100")));
            String status = borrowerInfoVo.getStatus();
                //（0：未提交，1：审核中， 2：审核通过， -1：审核不通过）
            switch (status){
                case "0":
                    borrowerInfoVo.setStatus("未提交");
                    break;
                case "1":
                    borrowerInfoVo.setStatus("审核中");
                    break;
                case "2":
                    borrowerInfoVo.setStatus("审核通过");
                    break;
                case "-1":
                    borrowerInfoVo.setStatus("审核不通过");
                    break;
            }
            //贷款用途
            String moneyUse = borrowerInfoVo.getMoneyUse(); // 1 2 3 4
            borrowerInfoVo.setMoneyUse(dictService.queryDictNameByDictCodeAndValue("moneyUse",
                    Integer.parseInt(moneyUse)));
            String returnMethod = borrowerInfoVo.getReturnMethod();
            borrowerInfoVo.setReturnMethod(dictService.queryDictNameByDictCodeAndValue("returnMethod",
                    Integer.parseInt(returnMethod)));

        });
        //将上面查询到的数据集合设置给分页对象
        page.setRecords(borrowerInfoVos);
    }

    @Override
    public BorrowInfoDetailVo getBorrowInfoDetailVo(String id) {
        //获取borrowInfo数据
        BorrowInfo borrowInfo = this.getById(id);
        BorrowInfoDetailVo vo = new BorrowInfoDetailVo();
        //1、借款人信息
        //根据borrowInfo中的userId查询借款人信息
        Borrower borrower = borrowerService.getOne(new LambdaQueryWrapper<Borrower>()
                .select(Borrower::getId)
                .eq(Borrower::getUserId, borrowInfo.getUserId()));
        //根据借款人id查询借款人详情数据
        BorrowerDetailVO borrowerDetailVO = borrowerService.selectBorrowerDetail(borrower.getId().toString());
        vo.setBorrower(borrowerDetailVO);
        //借款信息：BorrowerInfoVo
        BorrowerInfoVo borrowerInfoVo = new BorrowerInfoVo();
        borrowerInfoVo.setId(borrowInfo.getId());
        borrowerInfoVo.setAmount(borrowInfo.getAmount());
        borrowerInfoVo.setBorrowYearRate(borrowInfo.getBorrowYearRate().multiply(new BigDecimal("100")));
        borrowerInfoVo.setPeriod(borrowInfo.getPeriod());
        borrowerInfoVo.setCreateTime(borrowInfo.getCreateTime());
        borrowerInfoVo.setReturnMethod(dictService
                .queryDictNameByDictCodeAndValue("returnMethod",borrowInfo.getReturnMethod()));
        borrowerInfoVo.setMoneyUse(dictService
                .queryDictNameByDictCodeAndValue("moneyUse",borrowInfo.getMoneyUse()));
        switch(borrowInfo.getStatus()){
            case 0:
                borrowerInfoVo.setStatus("未提交");
                break;
            case 1:
                borrowerInfoVo.setStatus("审核中");
                break;
            case 2:
                borrowerInfoVo.setStatus("审核通过");
                break;
            case -1:
                borrowerInfoVo.setStatus("审核不通过");
                break;
        }

        vo.setBorrowInfo(borrowerInfoVo);

        return vo;
    }

    @Override
    public void borrowInfoApproval(BorrowInfoApprovalVO vo) {
        //1、更新借款信息的状态
        String id = vo.getId();
        Integer status = vo.getStatus();
        this.update(new LambdaUpdateWrapper<BorrowInfo>()
                .eq(BorrowInfo::getId, id)
                .set(BorrowInfo::getStatus, status));
        //2、如果借款信息审批状态为已通过，创建新标的
        BorrowInfo borrowInfo = this.getById(id);
        //审批状态为已通过
        if(borrowInfo.getStatus()==2){
            //创建新标的
            lendService.createLend(vo,borrowInfo);
        }

    }

}
